﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Resources;
using Microsoft.SharePoint.Utilities;
using System.Collections;
using System.Web.Caching;
using DVK.SP2007.Constants;

namespace DVK.SP2007
{
    /// <summary>
    /// JobsResourceManager provides resources from Dvk.resx file to Sharepoint Timer Jobs.
    /// <remarks>
    /// The resource assemblies are not accessible to the timer jobs, so an approach to load the data from .resx directly is used.
    /// </remarks>
    /// </summary>
    public class JobsResourceManager : IDvkResourceManager
    {
        Dictionary<string, string> _dict;
        /// <summary>
        /// Initializes a new instance of the <see cref="JobsResourceManager"/> class.
        /// </summary>
        public JobsResourceManager()
            : this(General.DvkResxFileName)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="JobsResourceManager"/> class.
        /// </summary>
        /// <param name="resourceFileName">Name of the resource file.</param>
        public JobsResourceManager(string resourceFileName)
        {
            _dict = GetResources(resourceFileName);
        }

        /// <summary>
        /// Gets the resources from cache or loads from resource file specified.
        /// If the filename is null then default is loaded - Dvk.resx.
        /// </summary>
        /// <param name="resourceFileName">Name of the resource file.</param>
        /// <returns></returns>
        private Dictionary<string, string> GetResources(string resourceFileName)
        {
            if (string.IsNullOrEmpty(resourceFileName))
                resourceFileName = General.DvkResxFileName;
            var cacheKey = Caching.JobsResources + "_" + resourceFileName;
            var cache = new CacheProvider().GetCache();
            if (cache[cacheKey] != null)
                return cache[cacheKey] as Dictionary<string, string>;

            //If we get here, then the cache was empty
            //Get the resources into dictionary
            string filepath = SPUtility.GetGenericSetupPath("Resources") + @"\" + resourceFileName;

            var dict = new Dictionary<string, string>();
            using (var resx = new ResXResourceReader(filepath))
            {
                foreach (DictionaryEntry item in resx)
                {
                    dict.Add(item.Key.ToString(), item.Value.ToString());
                }
            }

            //Cache it with file system dependency on .resx file in the Root resources folder of SharePoint
            var cacheDependency = new CacheDependency(filepath);
            cache.Insert(Caching.JobsResources, dict, cacheDependency);
            return dict;
        }

        #region IDvkResourceManager Members

        /// <summary>
        /// Gets the resource value based on key.
        /// </summary>
        /// <param name="key">The resource key.</param>
        /// <returns>resource value</returns>
        public string GetString(string key)
        {
            string sValue;
            if (_dict.TryGetValue(key, out sValue))
                return sValue;
            return null;
        }

        /// <summary>
        /// Gets the resource based on enum element.
        /// </summary>
        /// <typeparam name="T">type of enum</typeparam>
        /// <param name="enumValue">The enum element value.</param>
        /// <returns>localized string</returns>
        public string GetResourceBasedOnEnumElement<T>(T enumValue)
        {
            Type enumType = typeof(T);
            string name = Enum.GetName(enumType, enumValue);
            return GetString(enumType.Name + "_" + name);
        }

        /// <summary>
        /// Gets the resource based on enum element.
        /// The data inputed will be used in string.Format to fill in the data gaps in the localized string.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumValue">The enum value.</param>
        /// <param name="data">The data.</param>
        /// <returns>localized string</returns>
        public string GetResourceBasedOnEnumElement<T>(T enumValue, params object[] data)
        {
            Type enumType = typeof(T);
            string name = Enum.GetName(enumType, enumValue);
            var result = GetString(enumType.Name + "_" + name);
            if (result != null)
                return string.Format(result, data);
            return result;
        }

        #endregion
    }
}
